/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package desarrollosoft.ghce.vista.implementaciones;

import desarrollosoft.ghce.entidades.Componente;
import desarrollosoft.ghce.entidades.PlantillaEstudioLaboratorio;
import desarrollosoft.ghce.entidades.Sexo;
import desarrollosoft.ghce.entidades.UnidadMedida;
import desarrollosoft.ghce.entidades.ValorNormal;
import desarrollosoft.ghce.servicio.interfaces.IParserExcepciones;
import desarrollosoft.ghce.servicio.interfaces.IServicioPlantillas;
import java.util.ArrayList;
import java.util.List;
import org.zkoss.bind.BindUtils;
import org.zkoss.bind.Converter;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.Init;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.zk.ui.Execution;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.select.annotation.VariableResolver;
import org.zkoss.zk.ui.select.annotation.WireVariable;
import org.zkoss.zul.Messagebox;

/**
 *
 * @author ariel
 */
@VariableResolver(org.zkoss.zkplus.spring.DelegatingVariableResolver.class)
public class ControladoraVentanaDetallesPlantillaEstudioLaboratorio {
    
    @WireVariable("servicioPlantillas")
    private IServicioPlantillas servicioPlantillas;
    
    @WireVariable("parserExcepcionesPlantillas")
    private IParserExcepciones parserExcepciones;
    
    private PlantillaEstudioLaboratorio plantillaEstudioLaboratorio;
    private List<Componente> listaComponentes;
    private List<ValorNormal> listaValoresNormales;
    private List<UnidadMedida> listasUnidadMedida;
    private List<Sexo> listaSexos;
    private Componente componenteSeleccionado;
    private ValorNormal valorNormalSeleccionado;
    
    private Componente componenteDetalles; // solo para bindiar con los detalles de componente
    private ValorNormal valorNormalDetalles; // solo para bindiar con los detalles de valor normal
 
    private boolean habilitarBotonesComponente;
    private boolean habilitarGuardarCancelarComponente;
    private boolean habilitarBotonesValorNormal;
    private boolean habilitarGuardarCancelarValorNormal;
    
    private boolean habilitarBotonCrearComponente;
    private boolean habilitarBotonCrearValorNormal;
    
    private Estado estado;
    
    private enum Estado {
        TODO_DESHABILITADO,
        COMPONENTE_SELECCIONADO,
        CREANDO_COMPONENTE,
        MODIFICANDO_COMPONENTE,
        VALOR_NORMAL_SELECCIONADO,
        CREANDO_VALOR_NORMAL,
        MODIFICANDO_VALOR_NORMAL,
    }
    
    private Converter conversorDouble;
    private Converter conversorInt;
    
    @Init
    public void inicializar() {
        Execution ejecucion = Executions.getCurrent();
        plantillaEstudioLaboratorio = (PlantillaEstudioLaboratorio) ejecucion.getArg().get("plantillaEstudioLaboratorio");
        listaComponentes = servicioPlantillas.obtenerTodosComponentes(plantillaEstudioLaboratorio);
        listaSexos = servicioPlantillas.obtenerSexos();
        listasUnidadMedida = servicioPlantillas.obtenerUnidadesMedida();
        /* inicializaciones para que no fallen los bindings */
        componenteDetalles = new Componente();
        valorNormalDetalles = new ValorNormal();
        /* inicializo los conversores */
        conversorDouble = new ConversorDouble();
        conversorInt = new ConversorInt();
        /* seteo el estado inicial */
        setearEstado(Estado.TODO_DESHABILITADO);
    }

    private void setearEstado(Estado estado) {
        this.estado = estado;
        switch (estado) {
            case TODO_DESHABILITADO:
                //
                habilitarBotonCrearComponente = true;
                habilitarBotonCrearValorNormal = false;
                
                habilitarBotonesComponente = false;
                habilitarGuardarCancelarComponente = false;
                habilitarBotonesValorNormal = false;
                habilitarGuardarCancelarValorNormal = false;
                break;
            case COMPONENTE_SELECCIONADO:
                //
                habilitarBotonCrearComponente = true;
                habilitarBotonCrearValorNormal = true;
                
                habilitarBotonesComponente = true;
                habilitarGuardarCancelarComponente = false;
                habilitarBotonesValorNormal = false;
                habilitarGuardarCancelarValorNormal = false;
                break;
            case CREANDO_COMPONENTE:
                //
                habilitarBotonCrearComponente = false;
                habilitarBotonCrearValorNormal = false;
                
                habilitarBotonesComponente = false;
                habilitarGuardarCancelarComponente = true;
                habilitarBotonesValorNormal = false;
                habilitarGuardarCancelarValorNormal = false;
                break;
            case MODIFICANDO_COMPONENTE:
                //
                habilitarBotonCrearComponente = false;
                habilitarBotonCrearValorNormal = false;
                
                habilitarBotonesComponente = false;
                habilitarGuardarCancelarComponente = true;
                habilitarBotonesValorNormal = false;
                habilitarGuardarCancelarValorNormal = false;
                break;
            case VALOR_NORMAL_SELECCIONADO:
                //
                habilitarBotonCrearComponente = false;
                habilitarBotonCrearValorNormal = true;
                
                habilitarBotonesComponente = false;
                habilitarGuardarCancelarComponente = false;
                habilitarBotonesValorNormal = true;
                habilitarGuardarCancelarValorNormal = false;
                break;
            case CREANDO_VALOR_NORMAL:
                //
                habilitarBotonCrearComponente = false;
                habilitarBotonCrearValorNormal = false;
                
                habilitarBotonesComponente = false;
                habilitarGuardarCancelarComponente = false;
                habilitarBotonesValorNormal = false;
                habilitarGuardarCancelarValorNormal = true;
                break;
            case MODIFICANDO_VALOR_NORMAL:
                //
                habilitarBotonCrearComponente = false;
                habilitarBotonCrearValorNormal = false;
                
                habilitarBotonesComponente = false;
                habilitarGuardarCancelarComponente = false;
                habilitarBotonesValorNormal = false;
                habilitarGuardarCancelarValorNormal = true;
                break;
        } // termina switch
        BindUtils.postNotifyChange(null, null, this, "habilitarBotonesComponente");
        BindUtils.postNotifyChange(null, null, this, "habilitarGuardarCancelarComponente");
        BindUtils.postNotifyChange(null, null, this, "habilitarBotonesValorNormal");
        BindUtils.postNotifyChange(null, null, this, "habilitarGuardarCancelarValorNormal");
        
        BindUtils.postNotifyChange(null, null, this, "habilitarBotonCrearComponente");
        BindUtils.postNotifyChange(null, null, this, "habilitarBotonCrearValorNormal");
    }
    
    @NotifyChange({"listaValoresNormales","componenteDetalles","valorNormalDetalles"})
    @Command("seleccionaronComponente")
    public void seleccionaronComponente() {
        listaValoresNormales = servicioPlantillas.obtenerValoresNormales(componenteSeleccionado); // actualizo la lista de valores normales
        componenteDetalles = componenteSeleccionado;
        valorNormalDetalles = new ValorNormal();
        valorNormalSeleccionado = new ValorNormal();
        setearEstado(Estado.COMPONENTE_SELECCIONADO);
    }
    
    @NotifyChange("componenteDetalles")
    @Command("crearComponente")
    public void clickBotonCrearComponente() {
        componenteDetalles = new Componente();
        setearEstado(Estado.CREANDO_COMPONENTE);
    }
    
    @Command("modificarComponente")
    public void clickBotonModificarComponente() {
        setearEstado(Estado.MODIFICANDO_COMPONENTE);
    }
    
    @Command("eliminarComponente")
    public void clickBotonEliminarComponente() {
        // pido confirmacion
        Messagebox.show("¿Confirma que desea eliminar el Componente seleccionado?\n"
                + "Tambien se eliminarán los Valores Normales asociados a dicho componente", 
                "Confirme por favor",
                Messagebox.YES | Messagebox.NO, Messagebox.QUESTION,
                new EventListener() {
                    @Override
                    public void onEvent(Event evt) throws InterruptedException {
                        if (evt.getName().equals("onYes")) { // si confirma
                            try {
                                servicioPlantillas.eliminarComponente(componenteSeleccionado);
                                recargarComponentes();
                            } catch (Exception e) {
                                Messagebox.show(parserExcepciones.parsear( e.toString() ));
                                return;
                            }
                        }
                    }
                }
        );
    }
    
    private void recargarComponentes() {
        listaComponentes = servicioPlantillas.obtenerTodosComponentes(plantillaEstudioLaboratorio);
        BindUtils.postNotifyChange(null, null, this, "listaComponentes");
    }
    
    @NotifyChange({"listaComponentes","listaValoresNormales"})
    @Command("guardarComponente")
    public void clickBotonGuardarComponente() {
        /* uso ID para saber si se esta creando o modificando */
        if (componenteDetalles.getId() == null) { // creando
            componenteDetalles.setPlantillaEstudioLaboratorio(plantillaEstudioLaboratorio);
            try {
                servicioPlantillas.crearComponente(componenteDetalles);
            } catch (Exception ex) {
                Messagebox.show(parserExcepciones.parsear( ex.toString() ));
                return;
            }
        } else { // modificando
            try {
                servicioPlantillas.modificarComponente(componenteDetalles);
            } catch (Exception ex) {
                Messagebox.show(parserExcepciones.parsear( ex.toString() ));
                return;
            }
        }
        listaComponentes = servicioPlantillas.obtenerTodosComponentes(plantillaEstudioLaboratorio);
        listaValoresNormales = new ArrayList<>();
        setearEstado(Estado.TODO_DESHABILITADO);
    }
    
    @NotifyChange("componenteDetalles")
    @Command("cancelarGuardarComponente")
    public void clickBotonCancelarGuardarComponente() {
        if (estado.equals(Estado.CREANDO_COMPONENTE)) {
            componenteDetalles = new Componente();
            if (componenteSeleccionado != null) {
                componenteDetalles = componenteSeleccionado;
            }
            setearEstado(Estado.TODO_DESHABILITADO);
        } else if (estado.equals(Estado.MODIFICANDO_COMPONENTE)) {
            componenteDetalles = componenteSeleccionado;
            setearEstado(Estado.COMPONENTE_SELECCIONADO);
        }
    }
    
    @NotifyChange("valorNormalDetalles")
    @Command("seleccionaronValorNormal")
    public void seleccionaronValorNormal() {
        valorNormalDetalles = valorNormalSeleccionado;
        setearEstado(Estado.VALOR_NORMAL_SELECCIONADO);
    }
    
    @NotifyChange("valorNormalDetalles")
    @Command("crearValorNormal")
    public void clickBotonCrearValorNormal() {
        valorNormalDetalles = new ValorNormal();
        setearEstado(Estado.CREANDO_VALOR_NORMAL);
    }
    
    @Command("modificarValorNormal")
    public void clickBotonModificarValorNormal() {
        setearEstado(Estado.MODIFICANDO_VALOR_NORMAL);
    }
    
    @Command("eliminarValorNormal")
    public void clickEliminarValorNormal() {
        // pido confirmacion
        Messagebox.show("¿Confirma que desea Eliminar el Valor Normal seleccionado?", "Confirme por favor",
                Messagebox.YES | Messagebox.NO, Messagebox.QUESTION,
                new EventListener() {
                    @Override
                    public void onEvent(Event evt) throws InterruptedException {
                        if (evt.getName().equals("onYes")) { // si confirma
                            try {
                                servicioPlantillas.eliminarValorNormal(valorNormalSeleccionado);
                                recargarValoresNormales();
                            } catch (Exception e) {
                                Messagebox.show(parserExcepciones.parsear( e.toString() ));
                                return;
                            }
                        }
                    }
                }
        );
    }
    
    private void recargarValoresNormales() {
        listaValoresNormales = servicioPlantillas.obtenerValoresNormales(componenteSeleccionado);
        BindUtils.postNotifyChange(null, null, this, "listaValoresNormales");
    }
    
    @NotifyChange("listaValoresNormales")
    @Command("guardarValorNormal")
    public void clickBotonGuardarValorNormal() {
        if (!valido(valorNormalDetalles)) {
            return;
        }
        /* uso ID para saber si se esta creando o modificando */
        if (valorNormalDetalles.getId() == null) { // creando
            valorNormalDetalles.setComponente(componenteSeleccionado);
            try {
                servicioPlantillas.crearValorNormal(valorNormalDetalles);
            } catch (Exception ex) {
                Messagebox.show(parserExcepciones.parsear( ex.toString() ));
                return;
            }
        } else { // modificando
            try {
                servicioPlantillas.modificarValorNormal(valorNormalDetalles);
            } catch (Exception ex) {
                Messagebox.show(parserExcepciones.parsear( ex.toString() ));
                return;
            }
        }
        listaValoresNormales = servicioPlantillas.obtenerValoresNormales(componenteSeleccionado);
        setearEstado(Estado.TODO_DESHABILITADO); // ???
    }
    
    private boolean valido(ValorNormal valorNormal) {
        /*if (valorNormal.getSexo() == null) {
            Messagebox.show("Error con el Valor Normal, asegurese de Seleccionar Sexo");
            return false;
        } */
        /* AHORA PERMITO SEXO INDISTINTO (null) */
        if (valorNormal.getEdadMinima() == null || valorNormal.getEdadMinima() < 0) {
            Messagebox.show("Error con el Valor Normal, ingresar una Edad Mínima mayor o igual (>=) que 0");
            return false;
        }
        if (valorNormal.getEdadMaxima() == null || valorNormal.getEdadMaxima() < 0) {
            Messagebox.show("Error con el Valor Normal, ingresar una Edad Máxima mayor o igual (>=) que 0");
            return false;
        }
        if (valorNormal.getValorMinimo() == null && valorNormal.getValorMaximo() == null) {
            Messagebox.show("Error con el Valor Normal, ingresar mínimamente un Valor Minimo o un Valor Máximo");
            return false;
        }
        if (!(valorNormal.getEdadMinima() <= valorNormal.getEdadMaxima())) {
            Messagebox.show("Error con el Valor Normal, asegurese que Edad Mínima sea menor o igual (<=) que Edad Máxima");
            return false;
        }
        if (valorNormal.getValorMinimo() != null && valorNormal.getValorMaximo() != null) { // si cargaron los 2 valores
            if (!(valorNormal.getValorMinimo() < valorNormal.getValorMaximo())) {
                Messagebox.show("Error con el Valor Normal, asegurese que Valor Mínimo sea menor (<) que Valor Máximo");
                return false;
            }
        }
        return true;
    }
    
    @NotifyChange({"valorNormalDetalles","listaValoresNormales"})
    @Command("cancelarGuardarValorNormal")
    public void clickBotonCancelarGuardarValorNormal() {
        if (estado.equals(Estado.CREANDO_VALOR_NORMAL)) {
            valorNormalDetalles = new ValorNormal();
            if (valorNormalSeleccionado != null) {
                valorNormalDetalles = valorNormalSeleccionado;
            }
            setearEstado(Estado.COMPONENTE_SELECCIONADO);
        } else if (estado.equals(Estado.MODIFICANDO_VALOR_NORMAL)) {
            valorNormalDetalles = new ValorNormal(); // ??
            setearEstado(Estado.COMPONENTE_SELECCIONADO);
        }
        listaValoresNormales = servicioPlantillas.obtenerValoresNormales(componenteSeleccionado);
    }
    
    public List<Componente> getListaComponentes() {
        return listaComponentes;
    }

    public List<ValorNormal> getListaValoresNormales() {
        return listaValoresNormales;
    }

    public List<UnidadMedida> getListasUnidadMedida() {
        return listasUnidadMedida;
    }

    public List<Sexo> getListaSexos() {
        return listaSexos;
    }

    public Componente getComponenteSeleccionado() {
        return componenteSeleccionado;
    }

    public void setComponenteSeleccionado(Componente componenteSeleccionado) {
        this.componenteSeleccionado = componenteSeleccionado;
    }

    public ValorNormal getValorNormalSeleccionado() {
        return valorNormalSeleccionado;
    }

    public void setValorNormalSeleccionado(ValorNormal valorNormalSeleccionado) {
        this.valorNormalSeleccionado = valorNormalSeleccionado;
    }

    public Componente getComponenteDetalles() {
        return componenteDetalles;
    }

    public void setComponenteDetalles(Componente componenteDetalles) {
        this.componenteDetalles = componenteDetalles;
    }

    public ValorNormal getValorNormalDetalles() {
        return valorNormalDetalles;
    }

    public void setValorNormalDetalles(ValorNormal valorNormalDetalles) {
        this.valorNormalDetalles = valorNormalDetalles;
    }

    public boolean getHabilitarBotonesComponente() {
        return habilitarBotonesComponente;
    }

    public boolean getHabilitarGuardarCancelarComponente() {
        return habilitarGuardarCancelarComponente;
    }

    public boolean getHabilitarBotonesValorNormal() {
        return habilitarBotonesValorNormal;
    }

    public boolean getHabilitarGuardarCancelarValorNormal() {
        return habilitarGuardarCancelarValorNormal;
    }
    
    public boolean getHabilitarBotonCrearComponente() {
        return habilitarBotonCrearComponente;
    }
 
    public boolean getHabilitarBotonCrearValorNormal() {
        return habilitarBotonCrearValorNormal;
    }
    
    public Converter getConversorDouble() {
        return conversorDouble;
    }
    
    public Converter getConversorInt() {
        return conversorInt;
    }
}
